package com.yjw.apitestplugin;

import io.qameta.allure.CommonJsonAggregator;
import io.qameta.allure.Constants;
import io.qameta.allure.core.LaunchResults;
import io.qameta.allure.entity.Attachment;
import io.qameta.allure.entity.StageResult;
import io.qameta.allure.entity.Step;
import io.qameta.allure.entity.TestResult;

import java.util.*;
import java.util.stream.Collectors;

/**
 * custom plugin: display response code statistics
 */
public class CustomPlugin extends CommonJsonAggregator {

    public CustomPlugin() {
        super(Constants.WIDGETS_DIR, "widgets.json");
    }

    /**
     * convert data
     *
     * @param launches
     * @return
     */
    protected Object getData(List<LaunchResults> launches) {
        Result result = new Result();
        List<Integer> category = new ArrayList<>();
        List<Integer> data = new ArrayList<>();
        result.setCategory(category);
        result.setData(data);
        final List<TestResult> testResults = launches.stream()
                .flatMap(launch -> launch.getAllResults().stream())
                .collect(Collectors.toList());
        Map<Integer, Integer> map = new HashMap<>();
        for (TestResult testResult : testResults) {
            StageResult testStage = testResult.getTestStage();
            // testStage may be empty
            if (testStage == null) {
                continue;
            }
            List<Step> steps = testStage.getSteps();
            // steps may be empty
            if (steps == null || steps.size() == 0) {
                continue;
            }
            for (Step step : steps) {
                List<Attachment> attachments = step.getAttachments();
                // attachments may be empty
                if (attachments == null || attachments.size() == 0) {
                    continue;
                }
                for (Attachment attachment : attachments) {
                    String attName = attachment.getName();
                    String[] attNameArr = attName.split("\\|");
                    if (attNameArr.length != 2) {
                        continue;
                    }
                    String codeStr = attNameArr[1];
                    int code = Integer.parseInt(codeStr);
                    Integer codeNum = map.get(code);
                    if (codeNum == null) {
                        codeNum = 1;
                    } else {
                        codeNum++;
                    }
                    map.put(code, codeNum);
                }
            }
        }
        category.addAll(map.keySet());
        data.addAll(map.values());
        return result;
    }
}

/**
 * return data object
 */
class Result {

    private List<Integer> category;
    private List<Integer> data;

    public List<Integer> getCategory() {
        return category;
    }

    public void setCategory(List<Integer> category) {
        this.category = category;
    }

    public List<Integer> getData() {
        return data;
    }

    public void setData(List<Integer> data) {
        this.data = data;
    }
}